home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 30
/
PCMania CD30.iso
/
pcmania
/
graf30
/
tacs
/
writetag.c
< prev
Wrap
C/C++ Source or Header
|
1988-04-27
|
11KB
|
526 lines
/* ------------------------------------------------------------------ */
/* */
/* Developed by: Vijayakumar Rangarajan */
/* Name: writetag.c */
/* Function: Allows insertion of a new tag into the */
/* existing field list/ update of the existing */
/* tag value */
/* 9/22 Original, backedup as writetag.ins, works with all *.ins */
/* 10.10 pm with write_tags, and 'far' pointers in write_fields. */
/* */
/* 9/22 */
/* 10.25 New change to support direct file creation with write_tags */
/* without prior to write_fields. */
/* */
/* ------------------------------------------------------------------ */
#include "tifstruc.h"
extern long set_position();
extern long get_cpos();
extern int write_data();
extern int header_write();
extern int header_rewrite();
extern int field_data_write();
extern ifdstrc subfile, strpofst, strpbtcnt;
void new_check_tag();
extern void init_tif_hdr();
extern char tag_273;
extern char tag_279;
extern long field_data_pos;
extern long field_data_endpos;
extern long header_fil1_pos;
extern long ifdsize;
extern long next_val_pos;
extern short fields_exist;
extern short image_begin;
extern long get_tagval();
extern int find_type();
extern short rewrite_field_data();
extern int write_tag_val();
extern short field_mem_tab[];
extern int tot_tag_num;
void build_sbfile_tag();
short field_mem_tab1[256];
static short *field_cur_ptr;
static short *temp_field_cur_ptr;
static short build_tag_mem[6];
static short *new_tag_ptr;
static short *new_tag_pos;
static short new_tag_index;
static unsigned bytsize = 12; /* tag byte size = 12 */
short *build_one_tag(), find_len(), find_tag_pos(), update_temp_list();
int write_tag(filehndl, fdtype, tagnum, dataptr, length)
int filehndl;
short fdtype;
short tagnum;
short far *dataptr;
short length;
{
static int leng;
static short total_tag;
static long fdsize;
static long next_ifd_ptr;
long *ptr;
/* if already a list of tags exist, then check if insertion/update */
if (fields_exist)
{
tot_tag_num = field_mem_tab[0];
fdsize = (2+(tot_tag_num * 12));
leng = (int)fdsize;
memcpy ( field_mem_tab1, field_mem_tab, leng);
if (get_tagval(tagnum) <= 0)
{
if (image_begin) /* no insertion after image */
return(0); /* write*/
field_cur_ptr = (short *) field_mem_tab;
temp_field_cur_ptr = (short *) field_mem_tab1;
/* Check if stripbytcount and stripoffset tags to be included */
/* check_tag(tagnum, temp_field_cur_ptr); */
/* Build the tag data structure for the specified tag */
if((new_tag_ptr = build_one_tag(filehndl, tagnum, dataptr, fdtype, length)) <= 0)
return (0);
/* Find the position of the tag to be written in the existing field list */
if((new_tag_index = find_tag_pos(tagnum, field_mem_tab1)) < 0)
{
new_tag_index = field_mem_tab1[0];
}
new_tag_pos = ((field_mem_tab1 +1) + (new_tag_index * 6));
temp_field_cur_ptr = new_tag_pos;
new_check_tag(tagnum, temp_field_cur_ptr);
new_tag_pos = temp_field_cur_ptr;
/* Write the new tag data structure into the temp field list */
memcpy( new_tag_pos, new_tag_ptr, bytsize);
/* Advance the pointer in the new field buffer */
new_tag_pos += (bytsize/2);
/* Append the remaining tags from the original field list to the new list */
if(new_tag_index >= 0)
{
if(update_temp_list(field_mem_tab, new_tag_pos, new_tag_index) <= 0)
return(0);
}
/* Update the total tag number in the new field */
tot_tag_num++;
field_mem_tab1[0] = (short) tot_tag_num;
fdsize = (2+(tot_tag_num * 12));
temp_field_cur_ptr = field_mem_tab1;
temp_field_cur_ptr += (fdsize/2);
next_ifd_ptr = 0;
ptr = (long *) temp_field_cur_ptr;
*ptr = next_ifd_ptr;
fdsize +=4;
leng = (int) fdsize;
/* Copy the updated temp field list to the actual field data buffer */
memcpy( field_mem_tab, field_mem_tab1, leng);
/* Rewrite the field data, onto the file */
/* field_data_pos = next_val_pos; */
ifdsize = fdsize;
if (rewrite_field_data(filehndl) < 0)
return(0);
field_data_endpos = get_cpos(filehndl);
/* Update the first ifd pointer in the header and rewrite the header */
tiff_header.first_ifd_addr = field_data_pos;
if(header_rewrite(filehndl, header_fil1_pos) < 0)
return(0);
return(1);
}
/* The specified tag already exists in the field list, just update the value */
else
{
/* Update the tag value, use old 'write_tag' function */
if(write_tag_val(filehndl, fdtype, tagnum, dataptr, length) <= 0)
return(0);
return(1);
}
}
/* No fields exist, create a new field structure - a new file */
else
{
/* Create new fields with the new header */
fields_exist = 1;
tot_tag_num = 0;
ifdsize = 0;
init_tif_hdr();
header_fil1_pos = get_cpos(filehndl);
if (header_write(filehndl) < 0)
return(0);
next_val_pos = get_cpos(filehndl);
field_cur_ptr = (short *) field_mem_tab;
build_sbfile_tag(fdtype);
tot_tag_num++;
memcpy (&(field_mem_tab[1]), &subfile, sizeof(ifdstrc));
field_cur_ptr += 7;
if ((new_tag_ptr = build_one_tag(filehndl, tagnum, dataptr, fdtype,
length)) <= 0)
return(0);
field_data_pos = next_val_pos;
tot_tag_num++;
ifdsize = (2 + (tot_tag_num * 12));
memcpy(field_cur_ptr, build_tag_mem, bytsize);
field_mem_tab[0] = (short)tot_tag_num;
field_cur_ptr = field_mem_tab;
field_cur_ptr += (ifdsize/2);
next_ifd_ptr = 0;
ptr = (long *) field_cur_ptr;
*ptr = next_ifd_ptr;
ifdsize += 4;
if (field_data_write(filehndl, ifdsize) < 0)
return(0);
tiff_header.first_ifd_addr = field_data_pos;
if (header_rewrite(filehndl, header_fil1_pos) < 0)
return(0);
return(1);
}
}
/* --------------------------------------------- */
/* */
/* Build one tag data structure in build_tag_mem */
/* */
/* returns: pointer to the buffer */
/* */
/* --------------------------------------------- */
short *build_one_tag(filehand, tagno, pointr, filtype, siz_bytes)
short filehand;
short tagno;
short far *pointr;
short filtype;
short siz_bytes;
{
short *to_ptr;
short field_type;
short data_length;
long field_length, *ptr;
char *cptr;
char far *bptr;
if ((field_type = find_type(tagno)) < 0)
return((short *)-1);
to_ptr = build_tag_mem;
*to_ptr++ = tagno;
*to_ptr++ = field_type;
if((data_length = find_len(field_type)) <= 0)
return((short *)-1);
field_length = (long) ((siz_bytes + data_length -1)/data_length);
ptr = (long *) to_ptr;
*ptr++ = field_length;
to_ptr = (short *) ptr;
/* if(data_length <= 4) */
if(siz_bytes <= 4)
{
cptr = (char *) to_ptr;
bptr = (char far *) pointr;
while (siz_bytes-- > 0)
{
*cptr++ = *bptr++;
}
to_ptr = (short *) cptr;
}
else
{
if(set_position(filehand, next_val_pos) < 0)
return(0);
if (write_data(filehand, pointr, siz_bytes) < 0)
return(0);
ptr = (long *) to_ptr;
*ptr = next_val_pos;
next_val_pos = get_cpos(filehand);
field_data_pos = next_val_pos; /* 9/29 */
}
return (to_ptr = build_tag_mem);
}
/* ---------------------------- */
/* Find_len function */
/* Returns length in bytes for */
/* the specified field_type */
/* ---------------------------- */
short find_len(fld_type)
short fld_type;
{
short data_len;
switch (fld_type)
{
case 1:
data_len = 1;
break;
case 2:
data_len = 1;
break;
case 3:
data_len = 2;
break;
case 4:
data_len = 4;
break;
case 5:
data_len = 8;
break;
default:
data_len = 0;
}
return (data_len);
}
/* --------------------------------------- */
/* */
/* Function: Find tag position within the */
/* new field list for the new */
/* tag to be inserted */
/* */
/* Return: Tag position number in the */
/* buffer */
/* --------------------------------------- */
short find_tag_pos(tagnmr, field_mem)
short tagnmr;
short *field_mem;
{
short tag_index = 0;
short number_of_tags;
short *field_pointr;
number_of_tags = *field_mem++;
field_pointr = field_mem;
while (number_of_tags-- > 0)
{
if (tagnmr > *field_pointr)
{
field_pointr += 6;
tag_index += 1;
}
else
{
return(tag_index);
}
}
return (-1);
}
/* -------------------------------------- */
/* Function: Append the remaining existing*/
/* tag list to the new tag list */
/* after the insertion of the */
/* new tag. */
/* */
/* Return: status */
/* */
/* -------------------------------------- */
short update_temp_list(exist_field, new_field, tag_index)
short *exist_field;
short *new_field;
short tag_index;
{
short *from_ptr;
short *to_ptr;
short total_tags;
short i;
unsigned bytecount;
total_tags = *exist_field++;
from_ptr = (exist_field + (tag_index * 6));
to_ptr = new_field;
i = (total_tags - (tag_index)); /* because index begins from 0 */
bytecount = (i * 12);
/* update the total tag byte count by 12 more bytes */
ifdsize += 12;
memcpy(to_ptr, from_ptr, bytecount);
return(1);
}
/* Check the tag if stripoffset / stripbytecount tags are to be attached */
void new_check_tag(tag_num, field_ptr)
short tag_num;
short *field_ptr;
{
void new_build_strpofst_tag(), new_build_strpbytcnt_tag();
if (tag_num > TAG273)
{
if (tag_273 == 0)
{
tag_273 = 1;
new_build_strpofst_tag(field_ptr);
}
if (tag_num > TAG279)
{
if (tag_279 == 0)
{
tag_279 = 1;
new_build_strpbytcnt_tag(temp_field_cur_ptr);
}
}
}
}
/* Build stripoffset tag */
void new_build_strpofst_tag(field_ptr)
short *field_ptr;
{
strpofst.tagnum = TAG273;
strpofst.fieldtype = TLONG;
strpofst.fieldlen = 0;
strpofst.offset_rvalue = 0L;
memcpy (field_ptr, &strpofst, sizeof(ifdstrc));
temp_field_cur_ptr += 6;
tot_tag_num++;
}
/* Build stripbytecount tag */
void new_build_strpbytcnt_tag(field_ptr)
short *field_ptr;
{
strpbtcnt.tagnum = TAG279;
strpbtcnt.fieldtype = TLONG;
strpbtcnt.fieldlen = 0;
strpbtcnt.offset_rvalue = 0L;
memcpy (field_ptr, &strpbtcnt, sizeof(ifdstrc));
temp_field_cur_ptr += 6;
tot_tag_num++;
}